﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using NoNameGoServer.Client.Commands;

namespace NoNameGoServer.Client.Gui {
    public partial class MainForm : Form {
        private readonly NNGSClient _client;
        private readonly Dictionary<int, BoardForm> _boards = new Dictionary<int, BoardForm>();
        private int _lastBoardSize;
        private StoneColor _lastOpponentColor;

        public MainForm() {
            InitializeComponent();
            _client = new NNGSClient();
            _client.MatchRequestReceived += MatchRequestReceived;
            _client.MatchCreatedReceived += MatchCreatedReceived;
            _client.MoveMadeReceived += MoveMadeReceived;
            _client.CaptureMadeReceived += CaptureMadeReceived;
            _nngsClientConversation.NNGSClient = _client;
        }

        void CaptureMadeReceived(NNGSClient sender, CaptureMadeData captureMadeData) {
            BoardForm boardForm;
            if (_boards.TryGetValue(captureMadeData.GameNumber, out boardForm)) {
                boardForm.CaptureMade(captureMadeData.Letter, captureMadeData.Number);
            }
        }

        void MoveMadeReceived(NNGSClient sender, MoveMadeData moveMadeData) {
            BoardForm boardForm;
            if (_boards.TryGetValue(moveMadeData.GameNumber, out boardForm)) {
                boardForm.MoveMade(moveMadeData.Letter, moveMadeData.Number, moveMadeData.Color);
            }
        }

        void MatchCreatedReceived(NNGSClient sender, int matchNumber) {
            MethodInvoker mi = delegate {
                BoardForm frm = new BoardForm();
                _boards.Add(matchNumber, frm);
                frm.StartGame(_client, matchNumber, _lastBoardSize, _lastOpponentColor);
                frm.Show();
            };
            this.Invoke(mi);
        }

        void MatchRequestReceived(NNGSClient sender, MatchData matchData) {
            MethodInvoker mi = delegate {
                string msg = string.Format(
                  "Match requested from {0} who would play {1}, with a board size of {2}x{2}, time limit of {3}, byoyomi of {4}.\n'Yes' to accept.\n'No' to decline.",
                  matchData.OpponentUserName,
                  matchData.OpponentColor == StoneColor.White ? "White" : "Black",
                  matchData.BoardSize,
                  matchData.Time,
                  matchData.ByoyomiMinutes);
                if (MessageBox.Show(this, msg, "Match Request", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {
                    _lastBoardSize = matchData.BoardSize;
                    _lastOpponentColor = matchData.OpponentColor;
                    _client.EnqueueCommand(new MatchRequestCommand(
                        matchData.OpponentUserName,
                        matchData.OpponentColor == StoneColor.White ? StoneColor.Black : StoneColor.White,
                        matchData.BoardSize,
                        matchData.Time,
                        matchData.ByoyomiMinutes));
                } else {
                    _client.EnqueueCommand(new DeclineCommand(matchData.OpponentUserName));
                }
            };
            this.Invoke(mi);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
            if (_client != null) {
                _client.Dispose();
            }
            Close();
        }

        private void connectToolStripMenuItem_Click(object sender, EventArgs e) {
            ConnectDialog dlg = new ConnectDialog();
            if (dlg.ShowDialog(this) == DialogResult.OK) {
                _client.ConnectAsync(dlg.HostName, dlg.Port, dlg.UserName, dlg.Password);
            }
        }

        private void newGameToolStripMenuItem_Click(object sender, EventArgs e) {
            BoardForm frm = new BoardForm();
            frm.Show();
        }

        private void statsToolStripMenuItem_Click(object sender, EventArgs e) {
            StatsCommand statsCommand = new StatsCommand();
            statsCommand.Completed += statsCommand_Completed;
            _client.EnqueueCommand(statsCommand);
        }

        void statsCommand_Completed(Command sender, Command.CompletedArgs args) {
            StatsCommand.CompletedArgs statsArgs = (StatsCommand.CompletedArgs)args;
            StringBuilder sb = new StringBuilder();

            sb.AppendLine(string.Format("Player: {0}", statsArgs.Player));
            sb.AppendLine(string.Format("Game: {0}", statsArgs.Game));
            sb.AppendLine(string.Format("Language: {0}", statsArgs.Language));
            sb.AppendLine(string.Format("Rating: {0}", statsArgs.Rating));
            sb.AppendLine(string.Format("Rank: {0}", statsArgs.Rank));
            sb.AppendLine(string.Format("Is Rated: {0}", statsArgs.IsRated));
            sb.AppendLine(string.Format("Rated Games: {0}", statsArgs.RatedGames));
            sb.AppendLine(string.Format("Rank Set By Player: {0}", statsArgs.RankSetByPlayer));
            sb.AppendLine(string.Format("Wins: {0}", statsArgs.Wins));
            sb.AppendLine(string.Format("Losses: {0}", statsArgs.Losses));
            sb.AppendLine(string.Format("Idle Time: {0}", statsArgs.IdleTime));
            sb.AppendLine(string.Format("Address: {0}", statsArgs.Address));
            sb.AppendLine(string.Format("Country: {0}", statsArgs.Country));
            sb.AppendLine(string.Format("Registration Date: {0}", statsArgs.RegDate));
            sb.AppendLine(string.Format("Info: {0}", statsArgs.Info));
            sb.AppendLine(string.Format("Time: {0}", statsArgs.Time));
            sb.AppendLine(string.Format("Size: {0}", statsArgs.Size));
            sb.AppendLine(string.Format("Byo-Yomi Time: {0}", statsArgs.ByoYomiTime));
            sb.AppendLine(string.Format("Byo-Yomi Stones: {0}", statsArgs.ByoYomiStones));
            sb.AppendLine(string.Format("Verbose: {0}", statsArgs.Verbose));
            sb.AppendLine(string.Format("Bell: {0}", statsArgs.Bell));
            sb.AppendLine(string.Format("Quiet: {0}", statsArgs.Quiet));
            sb.AppendLine(string.Format("Shout: {0}", statsArgs.Shout));
            sb.AppendLine(string.Format("Automail: {0}", statsArgs.Automail));
            sb.AppendLine(string.Format("Open: {0}", statsArgs.Open));
            sb.AppendLine(string.Format("Looking: {0}", statsArgs.Looking));
            sb.AppendLine(string.Format("Client: {0}", statsArgs.Client));
            sb.AppendLine(string.Format("Kibitz: {0}", statsArgs.Kibitz));
            sb.AppendLine(string.Format("Chatter: {0}", statsArgs.Chatter));

            MessageBox.Show(sb.ToString(), "Stats", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}
